#ifndef __AV_PLAYER_H__
#define __AV_PLAYER_H__

#include <list>
#include <mutex>
#include <thread>
#include <vector>

#define SDL_MAIN_HANDLED
#include <SDL.h>

extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/imgutils.h>
#include <libavutil/pixfmt.h>
#include <libswresample/swresample.h>
#include <libswscale/swscale.h>
}

class AVPlayer {
  public:
    enum State {
        IDLE,    // 空闲
        INITED,  // 已初始化
        PLAYING, // 播放中
        PAUSED,  // 暂停
        COMPLETE,// 完成
        STOPPED, // 已停止
    };
    explicit AVPlayer();
    ~AVPlayer();

  public:
    int start(const char *input);
    void Init(void *winId, int winWidth, int winHeight);
    bool IsPlaying();
    void Pause();
    void Resume();

  private:
    AVFormatContext *format_context;
    void HandleVideo();
    void HandleAudio();
    std::vector<std::thread> work_threads;

    // 视频
    AVCodecContext *video_codec_context;
    std::list<AVPacket> video_packet_list;
    std::mutex video_mutex;
    bool PushVideoPacket(const AVPacket &pkt);
    bool PopVideoPacket(AVPacket &pkt);
    void ClearVideoPkt();

    // 音频
    AVCodecContext *audio_codec_context;
    std::list<AVPacket> audio_packet_list;
    std::mutex audio_mutex;
    bool PushAudioPacket(const AVPacket &pkt);
    bool PopAudioPacket(AVPacket &pkt);
    void ClearAudioPkt();

    void Read();
    void ChangeState(AVPlayer::State newState);
  private:
    bool read_eof = false;
    AVPlayer::State player_state = AVPlayer::State::IDLE;
    std::mutex state_mutex;
    int video_index = -1;
    int audio_index = -1;
    int frame_width = 0;
    int frame_height = 0;

  private:
    int initSDL(void *winid);
    SDL_Window *sdl_window;      // 窗口
    SDL_Renderer *sdl_renderer;  // 渲染器
    SDL_Texture *sdl_texture;    // 纹理
    int sdl_window_width = 720;  // 窗口宽度
    int sdl_window_height = 480; // 窗口高度
    static void audioCallBack(void *userdata, uint8_t *stream, int len);
};

#endif // __AV_PLAYER_H__
